/**
 * 
 */
package com.bemol.kernel.repository;

import java.io.Serializable;
import java.util.List;


/**
 * Repository system to store and search data
 * 
 * @author Samuel García Martínez
 *
 */
public interface Repository {
	
	/**
	 * Persist on the database system the transient_ instance.
	 * 
	 * @param transient_ instance to be persisted
	 * 
	 * @return Serializable instance's identifier
	 * 
	 * @throws RepositoryException if any error occurs
	 */
	public Serializable create(PersistenceObject transient_) throws RepositoryException;
	
	/**
	 * Loads the instance id for class clazz. If it doesn't exist this will return null
	 * 
	 * @param <T> Generic Type extending {@link PersistenceObject}
	 * @param clazz Type to be loaded
	 * @param id Type's identifier
	 * 
	 * @return Instance id for class clazz or null if it doesn't exist
	 * 
	 * @throws RepositoryException if any error occurs
	 */
	public <T extends PersistenceObject> T read(Class<T> clazz, Serializable id) throws RepositoryException;
	
	/**
	 * Updates non transient instance obj on the dabase system.
	 * 
	 * @param <T> Generic Type extending {@link PersistenceObject}
	 * @param obj non transient instance to be updated
	 * 
	 * @return updated instance
	 * 
	 * @throws RepositoryException if any error occurs
	 */
	public <T extends PersistenceObject> T update(T obj) throws RepositoryException;
	
	/**
	 * Removes from the database system given obj instance.
	 * 
	 * @param obj Instance to be removed
	 * 
	 * @throws RepositoryException if any error occurs
	 */
	public void delete(PersistenceObject obj) throws RepositoryException;
	
	/**
	 * Executes an Hibernate Language Query query on the database system
	 * 
	 * @param hql Properly formed HQL query
	 * 
	 * @return a List of {@link Object} according to given query
	 * 
	 * @throws RepositoryException if any error occurs
	 */
	public List<Object> executeSelect(String hql) throws RepositoryException;
	
	/**
	 * Executes an update or delete Hibernate Language Query query on the database system
	 * 
	 * @param hql Properly formed HQL query
	 * 
	 * @return the number of affected rows
	 * 
	 * @throws RepositoryException if any error occurs
	 */
	public int executeUpdate(String hql) throws RepositoryException;
	
	/**
	 * Returns the current {@link Session} associated to the thread
	 * 
	 * @return the current {@link Session} associated to the thread
	 * 
	 * @throws RepositoryException if any error occurs
	 */
	public Session getSession() throws RepositoryException;
}
